package com.edais.service.imp;

import com.edais.dao.UserExtractInfoDao;
import com.edais.dao.WithdrawsCashDao;
import com.edais.domain.ErrorMessageSetting;
import com.edais.domain.ExtractConfig;
import com.edais.domain.UserExtractInfo;
import com.edais.domain.UserRecePayCard;
import com.edais.domain.gift.PointGrade;
import com.edais.service.ErrorMessageService;
import com.edais.service.ThirdProductRouteService;
import com.edais.service.UserExtractInfoService;
import com.edais.service.WithdrawsCashService;
import com.edais.util.CommonUtil;
import com.edais.util.Consts;
import com.edais.util.JsonUtil;
import com.edais.util.Message;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service

public class WithdrawsCashServiceImp implements WithdrawsCashService {
	private static final Log logger = LogFactory.getLog(WithdrawsCashServiceImp.class);

	@Autowired
	private WithdrawsCashDao withdrawsCashDao;

	@Autowired
	private UserExtractInfoDao userextractInfoDao;

	@Autowired
	private ErrorMessageService errorMessageService;

	@Autowired
	private ThirdProductRouteService thirdProductRouteService;

	@Autowired
	private UserExtractInfoService userExtractInfoService;

	@Override
	public Map<String, Object> getWithdrawsCashItem(String jsonStr, String userId) throws Exception {
		String acctBalance = "0.00";
		Map<String, Object> rtnMap = new HashMap<String, Object>();

		/** (1.)获取提现费率,第三方的固定提现费 */
		String extractFixedFee = withdrawsCashDao.getExtractFeeRate(Consts.SystemSettingParam.EXTRACT_FIXED_FEE_MAX);// 第三方的固定提现费
		String extractFeeRate = withdrawsCashDao.getExtractFeeRate(Consts.SystemSettingParam.EXTRACT_FEE_RATE_CREDIT);// 提现费率
		/** (2.)获取账户余额(调用核心接口) */
		String rtnStr = CommonUtil.getCoreValue(jsonStr);// 构建json字符串
		logger.debug("JSON:" + rtnStr);
		JSONObject balanceRtnMap = JSONObject.fromObject(rtnStr);

		if (balanceRtnMap != null && "00000".equals(balanceRtnMap.get("rescode"))) {
			acctBalance = balanceRtnMap.get("ACCTBALANCE") + "";
		} else {
			throw new Exception("调用E300012核心接口发生异常" + balanceRtnMap.get("resmsg"));
		}
		/** (3.)获取用戶手机号或者邮箱 */
		// User user = userDao.getUserDetail(userId);
		// String mobile = user.getMobile();
		// String email = user.getEmail();

		// rtnMap.put("communication", null == mobile ? (null == email ? "" :
		// email) : mobile);// 手机号或者邮箱
		// rtnMap.put("balanceMoney",
		// Integer.parseInt(acctBalance)-Integer.parseInt(extractFixedFee));//
		// 可提现金额
		BigDecimal money = new BigDecimal(acctBalance).subtract(new BigDecimal(extractFixedFee));
		rtnMap.put("balanceMoney", (money.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : money).toString());// 可提现金额
		rtnMap.put("extractFee", extractFixedFee);// 提现手续费（单笔收费）
		rtnMap.put("extractFeeRate", extractFeeRate);// 提现手续费（费率）
		rtnMap.put("rescode", Consts.SUCCESS_CODE);
		rtnMap.put("resmsg", Consts.SUCCESS_DESCRIBE);
		rtnMap.put("resmsg_cn", "");

		return rtnMap;
	}

	@Override
	public String getExtractFeeRate(String key) throws Exception {
		return withdrawsCashDao.getExtractFeeRate(key);
	}

	@Override
	public UserRecePayCard getRecePayBankInfo(String isValid, String id, String userId) throws Exception {
		return this.withdrawsCashDao.getRecePayBankInfo(isValid, id, userId);
	}

	@Override
	public UserRecePayCard getRecePayBankInfoByUserId(String userId) throws Exception {
		return this.withdrawsCashDao.getRecePayBankInfoByUserId(userId);
	}

	/**
	 * 提现调用核心确认
	 *
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = false)
	@Override
	public Map<String, Object> dealWithdrawl(String extractType, String transCode, Map<String, Object> paramMap,
											 UserRecePayCard userRecePayCard, String thirdProductCode, String thirdBankCode, String thirdPlatformCode)
			throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		String userId = paramMap.get("userId").toString();
		String logInfo = "extractApply" + userId + "-";

		String extractMoney = paramMap.get("extractMoney").toString();
		BigDecimal extractFeeBD = BigDecimal.ZERO;
		BigDecimal extractFeeRateBD = BigDecimal.ZERO;
		BigDecimal extractFeePayBD = new BigDecimal(extractMoney);

		BigDecimal extractMoneyBD = new BigDecimal(extractMoney);
		UserExtractInfo userExtractInfo = userextractInfoDao.getUserExtractInfoForUpdate(paramMap);
		PointGrade userPg = userExtractInfoService.queryPointGradeByUserId(userId);
		logger.info(logInfo + "用户等级：" + userPg.getGrade());

		ExtractConfig userExtractConfig = userExtractInfoService.queryExtractConfigByPointGrade(userPg.getGrade());
		logger.info(logInfo + "用户提现特权：" + userExtractConfig.toString());
		SimpleDateFormat extractDaySdf = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat extractMonthSdf = new SimpleDateFormat("yyyy-MM");
		Date currentDate = new Date();
		if (userExtractInfo == null) {
			logger.info(logInfo + "用户提现信息为空，插入一条提现信息");
			String userMobile = paramMap.get("phoneNo") == null ? "" : paramMap.get("phoneNo").toString();
			userExtractInfo = new UserExtractInfo();
			userExtractInfo.setUserId(Integer.parseInt(userId));
			userExtractInfo.setUserMobile(userMobile);
			userExtractInfo.setUserName(userId);
			userExtractInfo.setExtractDay(extractDaySdf.format(currentDate));
			userExtractInfo.setExtractMonth(extractMonthSdf.format(currentDate));
			userExtractInfo.setExtractAmount(extractMoneyBD);
			if ("1".equals(extractType)) { // 普通提现
				userExtractInfo.setExtractNormalMonthNumber(1);
				userExtractInfo.setExtractNormalMonthAmount(extractMoneyBD);
				userExtractInfo.setExtractQuickDayNumber(0);
				userExtractInfo.setExtractQuickDayAmount(BigDecimal.ZERO);
			} else { // 快速提现
				userExtractInfo.setExtractNormalMonthNumber(0);
				userExtractInfo.setExtractNormalMonthAmount(BigDecimal.ZERO);
				userExtractInfo.setExtractQuickDayNumber(1);
				userExtractInfo.setExtractQuickDayAmount(extractMoneyBD);
			}
			userExtractInfo.setCreatePer(userId);
			userExtractInfo.setCreateTime(new Date());
			this.userextractInfoDao.insertUserExtractInfo(userExtractInfo);
		} else {
			// 普通提现判断单月提现次数，超过次数需要收取手续费
			if ("1".equals(extractType)) {
				if (extractMonthSdf.format(new Date()).equals(userExtractInfo.getExtractMonth())) {
					if (userExtractInfo.getExtractNormalMonthNumber() >= userExtractConfig.getNormalMonthNumber()) {
						extractFeeRateBD = userExtractConfig.getNormalFeeFate();
						extractFeeBD = extractMoneyBD.multiply(extractFeeRateBD).setScale(2, RoundingMode.UP);
						extractFeePayBD = extractMoneyBD.subtract(extractFeeBD);
						logger.info(logInfo + "提现金额：" + extractMoneyBD.toPlainString() + "，手续费："
								+ extractFeeBD.toPlainString() + "，到账金额：" + extractFeePayBD.toPlainString());
						if (BigDecimal.ZERO.compareTo(extractFeePayBD) >= 0) {
							logger.info(logInfo + "，到账金额小于等于0：" + extractFeePayBD.toPlainString() + "，提现失败");
							resultMap = errorMessageService.getErrorMessage("EXTRACT_ARRIVED_AMOUNT_IS_ZERO");
							resultMap.put("rescode", Consts.ERROR_CODE);
							resultMap.put("resmsg", Consts.ErrorMsg.MSG00001);
							resultMap.put("resmsg_cn", getErrorMessage(resultMap));
							return resultMap;
						}
					}
					userExtractInfo.setExtractNormalMonthNumber(userExtractInfo.getExtractNormalMonthNumber() + 1);
					userExtractInfo.setExtractNormalMonthAmount(
							userExtractInfo.getExtractNormalMonthAmount().add(extractMoneyBD));
				} else {
					userExtractInfo.setExtractNormalMonthNumber(1);
					userExtractInfo.setExtractNormalMonthAmount(extractMoneyBD);
				}
			}

			// 快速提现判断单日限额，单日次数，单笔限额，
			if ("2".equals(extractType)) {
				if (extractMoneyBD.compareTo(userExtractConfig.getQuickSingleAmount()) > 0) {
					logger.info(logInfo + "快速提现金额：" + extractMoneyBD.toPlainString() + "超过快速单笔提现限额："
							+ userExtractConfig.getQuickSingleAmount().toPlainString());
					resultMap = errorMessageService.getErrorMessage("EXCEED_QUICK_SINGLE_AMOUNT");
					resultMap.put("rescode", Consts.ERROR_CODE);
					resultMap.put("resmsg", Consts.ErrorMsg.MSG00001);
					resultMap.put("resmsg_cn", getErrorMessage(resultMap));
					return resultMap;
				}
				if (extractDaySdf.format(new Date()).equals(userExtractInfo.getExtractDay())) {
					if (userExtractInfo.getExtractQuickDayAmount().add(extractMoneyBD)
							.compareTo(userExtractConfig.getQuickDayAmount()) > 0) {
						logger.info(logInfo + "当天快速提现已提现：" + userExtractInfo.getExtractQuickDayAmount().toPlainString()
								+ "加本次快速提现：" + extractMoneyBD.toPlainString() + "超过快速提现单日限额："
								+ userExtractConfig.getQuickDayAmount());
						resultMap = errorMessageService.getErrorMessage("EXCEED_QUICK_DAY_AMOUNT");
						resultMap.put("rescode", Consts.ERROR_CODE);
						resultMap.put("resmsg", Consts.ErrorMsg.MSG00001);
						resultMap.put("resmsg_cn", getErrorMessage(resultMap));
						return resultMap;
					}
					if (userExtractInfo.getExtractQuickDayNumber()
							.compareTo(userExtractConfig.getQuickDayNumber()) >= 0) {
						resultMap = errorMessageService.getErrorMessage("EXCEED_QUICK_DAY_NUMBER");
						resultMap.put("rescode", Consts.ERROR_CODE);
						resultMap.put("resmsg", Consts.ErrorMsg.MSG00001);
						resultMap.put("resmsg_cn", getErrorMessage(resultMap));
						return resultMap;
					}
					userExtractInfo.setExtractQuickDayNumber(userExtractInfo.getExtractQuickDayNumber() + 1);
					userExtractInfo
							.setExtractQuickDayAmount(userExtractInfo.getExtractQuickDayAmount().add(extractMoneyBD));
				} else {
					userExtractInfo.setExtractQuickDayNumber(1);
					userExtractInfo.setExtractQuickDayAmount(extractMoneyBD);
				}
			}
			userExtractInfo.setExtractAmount(extractMoneyBD);
			this.userextractInfoDao.updateUserExtractInfo(userExtractInfo);
			logger.info(logInfo + "更新用户提现信息");
		}

		String extractPlatform = paramMap.get("extractPlatform").toString();
		paramMap.put("extractFeeRate", extractFeeRateBD.toString());
		paramMap.put("extractFee", extractFeeBD.toString());
		paramMap.put("extractFeePay", extractFeePayBD.toString());

		logger.info(logInfo + "发送核心数据:" + paramMap);
		String jsonStrDowithdrawsCash = CommonUtil.constructJsonStr(transCode, userId, paramMap);
		logger.info(logInfo + "：" +jsonStrDowithdrawsCash);
		String rtnStrDowithdrawsCash = CommonUtil.getCoreValue(jsonStrDowithdrawsCash);
		logger.info(logInfo + "返回数据:" + rtnStrDowithdrawsCash);
		JSONObject dowithdrawsCashRtnMap = JSONObject.fromObject(rtnStrDowithdrawsCash);

		if (dowithdrawsCashRtnMap != null && "00000".equals(dowithdrawsCashRtnMap.get("rescode"))) {
			if ("2".equals(extractType)) {
				Map<String, Object> withDrawApply = JsonUtil
						.getMapFromJsonString(dowithdrawsCashRtnMap.getString("withDrawApply"));
				thirdProductRouteService.quickWithDraw(withDrawApply, thirdProductCode, thirdBankCode, extractPlatform,
						thirdPlatformCode, userRecePayCard.getBank_name());
			}
		} else {
			logger.info(logInfo + "核心报错" + rtnStrDowithdrawsCash);
			throw new RuntimeException(Message.CnDescriptionExpression.WITHDRAW_ERROR);
		}
		resultMap.put("rescode", Consts.SUCCESS_CODE);
		resultMap.put("resmsg", Consts.SUCCESS_DESCRIBE);
		resultMap.put("resmsg_cn", Consts.SUCCESS_DESCRIBE);
		return resultMap;
	}

	/**
	 * 检查用户账户异常
	 */
	@Override
	public boolean userAccountCheck(String userId) {
		String logInfo = "检查用户账户异常" + userId;
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("userId", userId);
		Map resMap = CommonUtil.invokeCore(logInfo, "userAccountCheckService", paramsMap);
		boolean userCheck = false;
		String rescode = resMap.get("rescode").toString();
		if (rescode.equals(Consts.SUCCESS_CODE)) {
			userCheck = true;
		}
		return userCheck;
	}

	/**
	 * 获取返回的信息
	 *
	 * @param errorMessageMap
	 * @return
	 */
	public String getErrorMessage(Map<String, Object> errorMessageMap) {
		ErrorMessageSetting ems = (ErrorMessageSetting) errorMessageMap.get("errorMessage");
		String messageContent = ems.getMessage_content();
		return messageContent;
	}

	public static void main(String[] args) {
		BigDecimal aa = new BigDecimal("0.0011232");
		System.out.println(aa.setScale(2, RoundingMode.UP));
	}
}
